Specific error for suites in common but none good 
diff --git a/ChangeLog b/ChangeLog index b38d56f..efaadfb 100644 --- a/ChangeLog +++ b/ChangeLog 
@@ -6,6 +6,11 @@  * Certificate selection based on signature hash, prefering SHA-1 over SHA-2  for pre-1.2 clients when multiple certificates are available.   +Changes + * A specific error is now returned when there are ciphersuites in common + but none of them is usable due to external factors such as no certificate + with a suitable (extended)KeyUsage or curvem or no PSK set. +  = PolarSSL 1.3.9 released 2014-10-20  Security  * Lowest common hash was selected from signature_algorithms extension in 
diff --git a/include/polarssl/error.h b/include/polarssl/error.h index 7ce2828..6a1143f 100644 --- a/include/polarssl/error.h +++ b/include/polarssl/error.h 
@@ -91,7 +91,7 @@  * ECP 4 8 (Started from top)  * MD 5 4  * CIPHER 6 6 - * SSL 6 10 (Started from top) + * SSL 6 11 (Started from top)  * SSL 7 31  *  * Module dependent error code (5 bits 0x.00.-0x.F8.) 
diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h index 194e944..1e9fb39 100644 --- a/include/polarssl/ssl.h +++ b/include/polarssl/ssl.h 
@@ -146,6 +146,7 @@  #define POLARSSL_ERR_SSL_INTERNAL_ERROR -0x6C00 /**< Internal error (eg, unexpected failure in lower-level module) */  #define POLARSSL_ERR_SSL_COUNTER_WRAPPING -0x6B80 /**< A counter would wrap (eg, too many messages exchanged). */  #define POLARSSL_ERR_SSL_WAITING_SERVER_HELLO_RENEGO -0x6B00 /**< Unexpected message at ServerHello in renegotiation. */ +#define POLARSSL_ERR_SSL_NO_USABLE_CIPHERSUITE -0x6A80 /**< None of the common ciphersuites is usable (eg, no suitable certificate) */    /*  * Various constants 
diff --git a/library/error.c b/library/error.c index 73504d4..0095636 100644 --- a/library/error.c +++ b/library/error.c 
@@ -452,6 +452,8 @@  snprintf( buf, buflen, "SSL - A counter would wrap (eg, too many messages exchanged)" );  if( use_ret == -(POLARSSL_ERR_SSL_WAITING_SERVER_HELLO_RENEGO) )  snprintf( buf, buflen, "SSL - Unexpected message at ServerHello in renegotiation" ); + if( use_ret == -(POLARSSL_ERR_SSL_NO_USABLE_CIPHERSUITE) ) + snprintf( buf, buflen, "SSL - None of the common ciphersuites is usable (eg, no suitable certificate)" );  #endif /* POLARSSL_SSL_TLS_C */    #if defined(POLARSSL_X509_USE_C) || defined(POLARSSL_X509_CREATE_C) 
diff --git a/library/ssl_srv.c b/library/ssl_srv.c index 04608ee..384207a 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c 
@@ -903,7 +903,7 @@  #if defined(POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO)  static int ssl_parse_client_hello_v2( ssl_context *ssl )  { - int ret; + int ret, got_common_suite;  unsigned int i, j;  size_t n;  unsigned int ciph_len, sess_len, chal_len; @@ -1072,6 +1072,7 @@  }  }   + got_common_suite = 0;  ciphersuites = ssl->ciphersuite_list[ssl->minor_ver];  ciphersuite_info = NULL;  #if defined(POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE) @@ -1089,6 +1090,8 @@  p[2] != ( ( ciphersuites[i] ) & 0xFF ) )  continue;   + got_common_suite = 1; +  if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i],  &ciphersuite_info ) ) != 0 )  return( ret ); @@ -1098,9 +1101,17 @@  }  }   - SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) ); - - return( POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN ); + if( got_common_suite ) + { + SSL_DEBUG_MSG( 1, ( "got ciphersuites in common, " + "but none of them usable" ) ); + return( POLARSSL_ERR_SSL_NO_USABLE_CIPHERSUITE ); + } + else + { + SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) ); + return( POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN ); + }    have_ciphersuite_v2:  ssl->session_negotiate->ciphersuite = ciphersuites[i]; @@ -1132,7 +1143,7 @@    static int ssl_parse_client_hello( ssl_context *ssl )  { - int ret; + int ret, got_common_suite;  unsigned int i, j;  size_t n;  unsigned int ciph_len, sess_len; @@ -1552,6 +1563,7 @@  * (At the end because we need information from the EC-based extensions  * and certificate from the SNI callback triggered by the SNI extension.)  */ + got_common_suite = 0;  ciphersuites = ssl->ciphersuite_list[ssl->minor_ver];  ciphersuite_info = NULL;  #if defined(POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE) @@ -1568,6 +1580,8 @@  p[1] != ( ( ciphersuites[i] ) & 0xFF ) )  continue;   + got_common_suite = 1; +  if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i],  &ciphersuite_info ) ) != 0 )  return( ret ); @@ -1577,12 +1591,19 @@  }  }   - SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) ); - - if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) - return( ret ); - - return( POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN ); + if( got_common_suite ) + { + SSL_DEBUG_MSG( 1, ( "got ciphersuites in common, " + "but none of them usable" ) ); + ssl_send_fatal_handshake_failure( ssl ); + return( POLARSSL_ERR_SSL_NO_USABLE_CIPHERSUITE ); + } + else + { + SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) ); + ssl_send_fatal_handshake_failure( ssl ); + return( POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN ); + }    have_ciphersuite:  ssl->session_negotiate->ciphersuite = ciphersuites[i]; 
diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 2cf4b6e..a37ea93 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh 
@@ -1562,7 +1562,7 @@  "$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \  psk_identity=foo psk=abc123" \  0 \ - -S "SSL - The server has no ciphersuites in common" \ + -S "SSL - None of the common ciphersuites is usable" \  -S "SSL - Unknown identity received" \  -S "SSL - Verification of the message MAC failed"   @@ -1571,7 +1571,7 @@  "$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \  psk_identity=foo psk=abc123" \  1 \ - -s "SSL - The server has no ciphersuites in common" \ + -s "SSL - None of the common ciphersuites is usable" \  -S "SSL - Unknown identity received" \  -S "SSL - Verification of the message MAC failed"   @@ -1580,7 +1580,7 @@  "$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \  psk_identity=foo psk=abc123" \  1 \ - -S "SSL - The server has no ciphersuites in common" \ + -S "SSL - None of the common ciphersuites is usable" \  -s "SSL - Unknown identity received" \  -S "SSL - Verification of the message MAC failed"   @@ -1589,7 +1589,7 @@  "$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \  psk_identity=abc psk=dead" \  0 \ - -S "SSL - The server has no ciphersuites in common" \ + -S "SSL - None of the common ciphersuites is usable" \  -S "SSL - Unknown identity received" \  -S "SSL - Verification of the message MAC failed"   @@ -1598,7 +1598,7 @@  "$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \  psk_identity=def psk=beef" \  0 \ - -S "SSL - The server has no ciphersuites in common" \ + -S "SSL - None of the common ciphersuites is usable" \  -S "SSL - Unknown identity received" \  -S "SSL - Verification of the message MAC failed"   @@ -1607,7 +1607,7 @@  "$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \  psk_identity=ghi psk=beef" \  1 \ - -S "SSL - The server has no ciphersuites in common" \ + -S "SSL - None of the common ciphersuites is usable" \  -s "SSL - Unknown identity received" \  -S "SSL - Verification of the message MAC failed"   @@ -1616,7 +1616,7 @@  "$P_CLI force_ciphersuite=TLS-PSK-WITH-AES-128-CBC-SHA \  psk_identity=abc psk=beef" \  1 \ - -S "SSL - The server has no ciphersuites in common" \ + -S "SSL - None of the common ciphersuites is usable" \  -S "SSL - Unknown identity received" \  -s "SSL - Verification of the message MAC failed"